package com.siss.tenancy.user.utils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.siss.tenancy.exception.BusinessException;
import com.siss.tenancy.finals.SystemFinal;
import com.siss.tenancy.util.MapUtils;
import com.siss.tenancy.vo.SissDictItemVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 类名: DictValueToNameUtils.java
 * 描述: 根据字典value获取name
 * 创建人: yingw
 * 创建时间: 2018年9月25日下午4:12:41
 */
@SuppressWarnings("unchecked")
@Component
public class DictValueToNameUtils<T> {
	@Autowired
	private RedisTemplate redisTemplate;

/**
	 * 字典value 转换 name, 接收列表参数
	 * 
	 * @param list
	 * @param cb
	 * @return
	 * @throws Exception
	 */
	public List<T> value2Name(List<T> list, String key, String get, String set, DictValueToNameCallBack<T> cb) throws Exception{
    	
		if(list == null || list.size() <= 0){
			return list;
		}
		
		Class<T> clazz = (Class<T>) list.get(0).getClass();
		
		Method getTypeMethod = clazz.getMethod(get);  // 获取type
    	Method setTypeTextMethod = clazz.getMethod(set, String.class);  // 设置type文本   	
    	
    	List<String> valuelist = list.stream().map((e)->{
    		try {
				return String.valueOf(getTypeMethod.invoke(e));
			} catch (Exception e1) {
				throw new BusinessException(e1);
			}
    	}).filter((f)->{
    		return StringUtils.isNotBlank(f) && !"null".equals(f);
    	}).collect(Collectors.toList());
    	
    	if (valuelist.size() == 0) {
       		list.stream().forEach((e)->{
    			try {
    				setTypeTextMethod.invoke(e, "");
				} catch (Exception e1) {
					throw new BusinessException(e1);
				}
    		});
    		
    		return list;
    	}
    	
    	HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();

    	String json = ops.get(SystemFinal.REDIS_CACHE_KEY_DICTTYPE,key).toString();
		List<Map<String,Object>> mapList = new ArrayList<Map<String,Object>>();
		ObjectMapper objectMapper = new ObjectMapper();
		mapList = objectMapper.readValue(json, List.class);
		
		List<SissDictItemVO> dictItemVOs = mapList.stream().map((e)->{
			return (SissDictItemVO) MapUtils.mapToBean(e, SissDictItemVO.class); // linkedhashmap to bean
		}).collect(Collectors.toList());
    	
		// 合并结果集
		list.stream().forEach((e)->{
			
			boolean match = dictItemVOs.stream().anyMatch((x)->{
				
				try {
					// 匹配value
					String type = getTypeMethod.invoke(e).toString();
					if(type.equals(x.getDictValue())){
						setTypeTextMethod.invoke(e, x.getDictName()); // 设置name
						return true;
					}
				} catch (Exception e1) {
					throw new BusinessException(e1);
				}
				return false;
			});
			
			if(!match){
				try {
					setTypeTextMethod.invoke(e, "");  // 没有匹配缓存value, 置为空""
				} catch (Exception e1) {
					throw new BusinessException(e1);
				} 
			}
			
			if(cb != null){
				try {
					cb.callback(e);  // 回调
				} catch (Exception e1) {
					throw new BusinessException(e1);
				} 
			}
    		
		});
    	
    	return list;
    }
	
	/**
	 * 字典value 转换 name, 接收列表参数
	 * 
	 * @param list
	 * @param
	 * @return
	 * @throws Exception
	 */
	public List<T> value2Name(List<T> list, String key, String get, String set) throws Exception{
    	
		return this.value2Name(list, key, get,set, null);
    }
	
	/**
	 * 字典value 转换 name, 接收单个对象参数
	 * 
	 * @param t
	 * @return
	 * @throws Exception
	 */
	public T value2Name(T t, String key, String get, String set) throws Exception{
		
		if(t == null){
			return t;
		}
		
		Class<T> clazz = (Class<T>) t.getClass();
	
    	Method getTypeMethod = clazz.getMethod(get);  // 获取type
    	Method setTypeTextMethod = clazz.getMethod(set, String.class);  // 设置type文本
    	String type =  String.valueOf(getTypeMethod.invoke(t)); //value
    	if(null == type || "null".equals(type)){
			return t;
		}
    	HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
    	if(!ops.hasKey(SystemFinal.REDIS_CACHE_KEY_DICTTYPE, key)){ // 缓存没命中
    		//缓存失败
			try {
				setTypeTextMethod.invoke(t, "");
			} catch (Exception e1) {
				throw new BusinessException(e1);
			}
    		
    		return t;
    	}
		String[] valueArry = type.split(",");
		String result = "";
    	String json = ops.get(SystemFinal.REDIS_CACHE_KEY_DICTTYPE,key).toString();
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		ObjectMapper objectMapper = new ObjectMapper();
		list = objectMapper.readValue(json, List.class);
		
		List<SissDictItemVO> dictItemVOs = list.stream().map((e)->{
			return (SissDictItemVO)MapUtils.mapToBean(e, SissDictItemVO.class); // linkedhashmap to bean
		}).collect(Collectors.toList());
		for (String s : valueArry) {
			result += (dictItemVOs.stream().filter(x -> x.getDictValue().equals(s)).map(e -> e.getDictName()).collect(Collectors.joining(","))+",");
		}
		result = StringUtils.strip(result,",");
		/*boolean match = dictItemVOs.stream().anyMatch((x)->{
			
			try {
				// 匹配value
				if(type.equals(x.getDictValue())){
					setTypeTextMethod.invoke(t, x.getDictName()); // 设置name
					return true;
				}
			} catch (Exception e1) {
				throw new BusinessException(e1);
			}
			return false;
		});*/
		setTypeTextMethod.invoke(t, result);
		/*if(!match){
			try {
				// 没有匹配缓存value, 置为空""
				setTypeTextMethod.invoke(t, result);
			} catch (Exception e1) {
				throw new BusinessException(e1);
			} 
		}*/
		
		return t;
	}
	
	/**
	 * 文件类别文本
	 * @return
	 * @throws Exception 
	 * @throws JsonMappingException 
	 * @throws JsonParseException 
	 */
	/*public String getTypeText() throws JsonParseException, JsonMappingException, Exception {
		if(this.type != null){
			HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
	    	if(ops.hasKey(SystemFinal.REDIS_CACHE_KEY_DICTTYPE, DictFinal.SRBA_FILE_TYPE)){ // 缓存命中
	    		String str = ops.get(SystemFinal.REDIS_CACHE_KEY_DICTTYPE,DictFinal.SRBA_FILE_TYPE).toString();
	    		//Map<String,String> map = JSON.parseObject(ops.get(SystemFinal.REDIS_CACHE_KEY_DICTTYPE,DictFinal.SRBA_FILE_TYPE).toString(),Map.class);
	    		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
	    		ObjectMapper objectMapper = new ObjectMapper();
	    		list = objectMapper.readValue(str, List.class);
	    		
	    		List<SissDictItemVO> dictItemVOs = list.stream().map((e)->{
	    			return (SissDictItemVO) com.szyf.siss.biz.common.util.MapUtils.mapToBean(e, SissDictItemVO.class); // linkedhashmap to bean
	    		}).collect(Collectors.toList());
	    		
	    		if(dictItemVOs != null){
	    			 for (Iterator iterator = dictItemVOs.iterator(); iterator.hasNext();) {           

	    				 SissDictItemVO vo= (SissDictItemVO) iterator.next(); 
                          if(vo.getDictValue().equals(this.type))
	    		             return vo.getDictName();
	    		     }
	    			 
	    			dictItemVOs.stream().filter(e->e.getDictValue().equals(this.type)).map((m)->{
	    	        	return m.getDictName();}).forEach(System.out::println);
	    			 SissDictItemVO vo=  dictItemVOs.stream().filter(e->e.getDictValue().equals(this.type)).findAny()
	    		                .orElse(null);
	    			 return vo.getDictName();
	    		}
	    		else
	    		return "";
	    	}
			
		}
		return "";
	}*/

	public String getDictNameByValue(String value,String dictKey){
		String name = "";
		HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
		if(!ops.hasKey(SystemFinal.REDIS_CACHE_KEY_DICTTYPE, dictKey)){
			// 缓存没命中
			return name;
		}
		try {
			String json = ops.get(SystemFinal.REDIS_CACHE_KEY_DICTTYPE, dictKey).toString();
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			ObjectMapper objectMapper = new ObjectMapper();
			list = objectMapper.readValue(json, List.class);
			List<SissDictItemVO> dictItemVOs = list.stream().map((e) -> {
				// linkedhashmap to bean
				return (SissDictItemVO) MapUtils.mapToBean(e, SissDictItemVO.class);
			}).collect(Collectors.toList());
			List<SissDictItemVO> vos = dictItemVOs.stream().filter(e -> value.equals(e.getDictValue())).collect(Collectors.toList());
			if(!vos.isEmpty()){
				name = vos.get(0).getDictName();
			}
			return name;
		}catch(Exception e){
			e.printStackTrace();
		}
		return name;
	}
    
	/**
	 * @Description 獲取value
	 *  * @param null
	 * @return 
	 * @author dql
	 * @Date 2020/9/8 11:52
	 **/
    public String getDictValueByName(String name,String dictKey){
        String value = "";
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
        if(!ops.hasKey(SystemFinal.REDIS_CACHE_KEY_DICTTYPE, dictKey)){
            // 缓存没命中
            return value;
        }
        try {
            String json = ops.get(SystemFinal.REDIS_CACHE_KEY_DICTTYPE, dictKey).toString();
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            ObjectMapper objectMapper = new ObjectMapper();
            list = objectMapper.readValue(json, List.class);
            List<SissDictItemVO> dictItemVOs = list.stream().map((e) -> {
                // linkedhashmap to bean
                return (SissDictItemVO) MapUtils.mapToBean(e, SissDictItemVO.class);
            }).collect(Collectors.toList());
            List<SissDictItemVO> vos = dictItemVOs.stream().filter(e -> name.equals(e.getDictName())).collect(Collectors.toList());
            if(!vos.isEmpty()){
                value = vos.get(0).getDictValue();
            }
            return value;
        }catch(Exception e){
            e.printStackTrace();
        }
        return name;
    }
}
